package com.szholly.pro.watergas_server.ps.android.controller;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;

import com.szholly.data.general.GlobalParameter;
import com.szholly.data.general.RowBase;
import com.szholly.pro.watergas_server.common.data.DataUtil;
import com.szholly.pro.watergas_server.ps.android.common.*;
import com.szholly.pro.watergas_server.ps.data.OperationGroupRow;
import com.szholly.pro.watergas_server.ps.monitor.MonitorDataFormater;
import com.szholly.pro.watergas_server.ps.service.RemoteService;
import com.szholly.utils.util.StringUtils;
import org.springframework.util.CollectionUtils;

public class SewageService {
	private final MonitorDataFormater mFormater = MonitorDataFormater.getInstance();

	// 获取历史数据界面初始化数据
	public String getHistoryDataInitData(String factoryId) {
		Map<String, Object> resultMap = new HashMap<>();
		try {
			List<RowBase> stationList = AndroidSewageDomainManager.getInstance().getStationList(factoryId);
			resultMap.put("stationList", stationList);
		} catch (Exception e) {
			return ResultUtils.getToastResult(e);
		}

		try {
			Map<String, List<RowBase>> parameterMap = AndroidSewageDomainManager.getInstance().getParameterMap(factoryId);
			resultMap.put("parameterMap", parameterMap);
		} catch (Exception e) {
			return ResultUtils.getToastResult(e);
		}
		return ResultUtils.getToastResult(resultMap);
	}

	// 获取历史数据界面初始化数据
	public Map<String, Object> getWarnList(String userId, String unitName, String stationId, String isRecover, String startTime, String endTime,
			int pageIndex) throws Exception {
		RowBase groupRow = CommonSqlUtils.getGroupRow(userId);
		String groupCode = groupRow == null ? null : groupRow.getSafeString(OperationGroupRow.FIELD_Guid);
		
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		parms.add(new GlobalParameter("startTime", startTime));
		parms.add(new GlobalParameter("endTime", endTime));
		String sql = "select t.station_code \"stationId\",\n"
				+ "       t.is_recover \"isRecover\",\n"
				+ "       t1.S_DOMAINCAPTION \"alarmType\",\n"
				+ "       t2.S_DOMAINCAPTION \"parameterName\",\n"
				+ "       t.continue_time||'(分钟)' \"continueTime\",\n"
				+ "       t.alarm_value \"alarmValue\",\n"
				+ "       to_char(t.start_time, 'yyyy-mm-dd hh24:mi:ss') \"startTime\",\n"
				+ "       to_char(t.recover_time, 'yyyy-mm-dd hh24:mi:ss') \"recoverTime\",\n"
				+ "       t2.S_UNIT\n"
				+ "  from OP_ALAR_INFO t\n"
				+ "  left join data_defulatdomain t1\n"
				+ "    on t1.S_DOMAINNAME = '报警类型'\n"
				+ "   and t1.s_domaincode = t.type\n"
				+ "  left join data_defulatdomain t2\n"
				+ "    on t2.S_DOMAINNAME = 'MONITOR_PARAM'\n"
				+ "   and t2.s_domaincode = t.param\n"
				+ "  left join BC_SITE_INFO t3\n"
				+ "    on t3.code = t.station_code\n"
				+ "  left join DATA_DEFULATDOMAIN t4\n"
				+ "    on t4.S_DOMAINNAME = '政区'\n"
				+ "   and length(t4.s_id) = '2'\n"
				+ "   and SUBSTR(t3.CODE, 3, 2) = t4.s_id\n"
				+ " where 1 = 1 and t.continue_time > 1\n";
		if ("1".equals(isRecover)) {
			sql += "   and t.IS_RECOVER = 1\n";
		} else if ("0".equals(isRecover)) {
			// 0和2都表示报警中
			sql += "   and t.IS_RECOVER <> 1\n";
		}
		// 行政分区和站点编号，优先使用站点编号
		if (!StringUtils.IsNullOrSpace(stationId)) {
			parms.add(new GlobalParameter("stationId", stationId));
			sql += "   and t3.code = @stationId\n";
		} else {
			if (!StringUtils.IsNullOrSpace(groupCode)) {
				parms.add(new GlobalParameter("groupCode", groupCode));
				sql += " and t.station_code in\n"
						+ "       (select distinct t.station_id\n"
						+ "          from OPERATION_GROUP_STATION_ASSO t\n"
						+ "         where t.operation_group_id = @groupCode)";
			} else {
				sql += " and t3.station_category in ('0','1') ";
			}

			if (!StringUtils.IsNullOrSpace(unitName)) {
				parms.add(new GlobalParameter("unitName", unitName));
				sql += "   and t4.S_DOMAINCAPTION = @unitName\n";
			}
		}
		sql += "   and t.start_time between to_date(@startTime, 'yyyy-mm-dd') and\n"
				+ "       to_date(@endTime, 'yyyy-mm-dd') + 1\n"
				+ "  order by t.start_time desc";
		int rowsCount = SqlUtils.getRowsCount(sql, parms);
		int upRowLimit = pageIndex * 25;
		int downRowLimit = (pageIndex - 1) * 25;
		parms.add(new GlobalParameter("upRowLimit", upRowLimit));
		parms.add(new GlobalParameter("downRowLimit", downRowLimit));
		String pageSql = "select * from (\n"
				+ "select t.*,ROWNUM oracle_rn from (\n"
				+ sql
				+ ") t where ROWNUM <=@upRowLimit\n"
				+ ") t where t.oracle_rn >@downRowLimit";
		List<RowBase> rows = DataUtil.getSelectRows(pageSql, parms);
		// 处理数据 移除没用的字段oracle_rn，修改原有的科学计数法
		if (!CollectionUtils.isEmpty(rows)) {
			for (RowBase rowBase : rows) {
				String unit = (String) rowBase.get("S_UNIT");
				String alarmValue = (String) rowBase.get("alarmValue");
				rowBase.remove("ORACLE_RN");
				rowBase.remove("S_UNIT");
				rowBase.put("alarmValue", getAlarmValueString(alarmValue, unit));
			}
		}
		AndroidPageInfo pageInfo = AndroidPageInfo.create(rowsCount, 25, pageIndex);
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("data", NonNullUtil.toList(rows));
		resultMap.put("pageInfo", pageInfo);
		return resultMap;
	}

	/**
	 * 获取报警状态描述
	 */
	public List<String> getWarnStateDes(String stationCode) throws Exception {
		ValidUtils.hasText(stationCode, "站点编号为空,报警状态详情获取失败");
		List<GlobalParameter> parms = new ArrayList<>();
		parms.add(new GlobalParameter("stationCode", stationCode));
		String sql = "select distinct t3.S_DOMAINCAPTION\n"
				+ "  from OP_ALAR_INFO t\n"
				+ "  left join data_defulatdomain t3\n"
				+ "    on t3.S_DOMAINCODE = t.type\n"
				+ " where t3.S_DOMAINNAME = '报警类型'\n"
				+ "   and t.IS_RECOVER <> 1\n"
				+ "   and t.continue_time > 1\n"
				+ "   and t3.S_DOMAINCAPTION is not null\n"
				+ "   and t.STATION_CODE = @stationCode";
		List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
		List<String> warnStateDesList = new ArrayList<>();
		if (!CollectionUtils.isEmpty(rows)) {
			for (RowBase rowBase : rows) {
				warnStateDesList.add(rowBase.getSafeString("S_DOMAINCAPTION"));
			}
		}
		return warnStateDesList;
	}

	/**
	 * 获取实时数据
	 * 
	 * @param factoryId
	 *            工厂编号
	 * @return
	 */
	public String getRuntimeData(String factoryId) {
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		boolean isSurface = factoryId.contains("surface");
		String sql;
		if (isSurface) {
			parms.add(new GlobalParameter("factoryId", factoryId.substring(7)));
			sql = "SELECT T1.DEVICE_NUM,\n"
					+ "       T2.NAME,\n"
					+ "       T2.NAME FLOW_TYPE\n"
					+ "  FROM BC_COLLECTION_INFO T1\n"
					+ " WHERE T1.SITE_ID = @factoryId\n";
		} else {
			parms.add(new GlobalParameter("factoryId", factoryId));
			sql = "SELECT T1.DEVICE_NUM,\n"
					+ "       T2.NAME,\n"
					+ "       CASE T2.FLOW_TYPE\n"
					+ "         WHEN N'0' THEN\n"
					+ "          '进水口'\n"
					+ "         ELSE\n"
					+ "          '出水口'\n"
					+ "       END AS FLOW_TYPE\n"
					+ "  FROM BC_COLLECTION_INFO T1\n"
					+ "  left join BC_SITE_INFO T2\n"
					+ "    ON T1.SITE_ID = T2.EXP_NO\n"
					+ " WHERE T2.WWTP_ID = @factoryId\n"
					+ " ORDER BY T2.FLOW_TYPE";
		}
		try {
			List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
			List<Map<String, String>> stationList = new ArrayList<Map<String, String>>();
			Map<String, List<Map<String, String>>> runtimeData = new HashMap<String, List<Map<String, String>>>();
			Map<String, String> dateTimeData = new HashMap<String, String>();
			if (!CollectionUtils.isEmpty(rows)) {
				for (RowBase rowBase : rows) {
					Map<String, String> stationMap = new HashMap<String, String>();
					String deviceNum = rowBase.getSafeString("DEVICE_NUM");
					String stationName = rowBase.getSafeString("NAME");
					// 通过站点名称获取水口名称
					String flowTypeName = null;
					int indexOf = stationName.indexOf("水口");
					if (indexOf >= 1) {
						flowTypeName = stationName.substring(indexOf - 1, stationName.length());
					} else {
						flowTypeName = stationName;
					}

					stationMap.put("name", stationName);
					stationMap.put("deviceNum", deviceNum);
					stationMap.put("flowTypeName", flowTypeName);
					stationList.add(stationMap);

					// 获取实时数据时间
					List<RowBase> stationHouseData = RemoteService.getInstance().getStationHouseData(deviceNum);
					dateTimeData.put(deviceNum, stationHouseData.get(0).getSafeString("DATATIME"));

					// 获取实时数据
					HashMap<String, RowBase> stationRealTimeData = RemoteService.getStationRealTimeData(deviceNum);
					List<Map<String, String>> realDataList = getRealDataList(stationRealTimeData);
					runtimeData.put(deviceNum, realDataList);
				}
			}
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("stationList", stationList);
			resultMap.put("runtimeData", runtimeData);
			resultMap.put("dateTimeData", dateTimeData);
			return ResultUtils.getToastResult(resultMap);
		} catch (Exception e) {
			return ResultUtils.getToastResult(e);
		}
	}

	public String getSurfaceRuntimeData(String factoryId) {
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		parms.add(new GlobalParameter("factoryId", factoryId));
		String sql = "select T1.DEVICE_NUM, T2.NAME\n"
				+ "  from BC_COLLECTION_INFO t1\n"
				+ "  left join BC_SITE_INFO t2 ON T1.SITE_ID = T2.EXP_NO\n"
				+ " where t1.SITE_ID = 'WS050500500084'";

		try {
			List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
			List<Map<String, String>> stationList = new ArrayList<Map<String, String>>();
			Map<String, List<Map<String, String>>> runtimeData = new HashMap<String, List<Map<String, String>>>();
			Map<String, String> dateTimeData = new HashMap<String, String>();
			if (!CollectionUtils.isEmpty(rows)) {
				for (RowBase rowBase : rows) {
					Map<String, String> stationMap = new HashMap<String, String>();
					String deviceNum = rowBase.getSafeString("DEVICE_NUM");
					String stationName = rowBase.getSafeString("NAME");
					stationMap.put("name", stationName);
					stationMap.put("deviceNum", deviceNum);
					stationList.add(stationMap);
					// 获取实时数据时间
					List<RowBase> stationHouseData = RemoteService.getInstance().getStationHouseData(deviceNum);
					dateTimeData.put(deviceNum, stationHouseData.get(0).getSafeString("DATATIME"));
					// 获取实时数据
					HashMap<String, RowBase> stationRealTimeData = RemoteService.getStationRealTimeData(deviceNum);
					List<Map<String, String>> realDataList = getRealDataList(stationRealTimeData);
					runtimeData.put(deviceNum, realDataList);
				}
			}
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("stationList", stationList);
			resultMap.put("runtimeData", runtimeData);
			resultMap.put("dateTimeData", dateTimeData);
			return ResultUtils.getToastResult(resultMap);
		} catch (Exception e) {
			return ResultUtils.getToastResult(e);
		}
	}

	/**
	 * 解析实时数据
	 * 
	 * @param dataMap
	 *            包含字段isAlarm、value、name、id
	 * @return
	 */
	private List<Map<String, String>> getRealDataList(HashMap<String, RowBase> dataMap) {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		if (dataMap == null || dataMap.size() == 0) {
			return list;
		}
		Iterator<String> iterator = dataMap.keySet().iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();
			RowBase rowBase = dataMap.get(key);
			Map<String, String> beanMap = new HashMap<String, String>();
			String valueStr = rowBase.getSafeString("MEAS_NORMAL");
			String unit = rowBase.getSafeString("UNIT");

			// 判断是否报警
			Double alarmUp = optDouble(rowBase.getSafeString("ALARMUP"), Double.MAX_VALUE);
			Double alarmDown = optDouble(rowBase.getSafeString("ALARMDOWN"), Double.MIN_VALUE);
			Double value = optDouble(valueStr, null);
			if (value == null) {
				beanMap.put("isAlarm", "0");
			} else {
				beanMap.put("isAlarm", (value > alarmDown && value < alarmUp) ? "0" : "1");
			}

			// 判断是否采用了科学计数法
			String wholeValue = optWholeValue(valueStr);
			if (StringUtils.IsNullOrSpace(wholeValue)) {
				beanMap.put("value", "");
			} else if (StringUtils.IsNullOrSpace(unit)) {
				beanMap.put("value", wholeValue);
			} else {
				beanMap.put("value", wholeValue + unit);
			}

			// 参数名和参数ID
			beanMap.put("name", rowBase.getSafeString("POLLNAME"));
			beanMap.put("id", key);
			list.add(beanMap);
		}
		return list;
	}

	// 获取一天的小时数据 (value,parameterCode,time)
	public List<RowBase> getOneDayHourData(String stationCode, DateTime dateTime) throws Exception {
		ValidUtils.hasText(stationCode, "站点编号为空，无法获取一天的小时数据");
		ValidUtils.notNull(dateTime, "日期为空，无法获取一天的小时数据");
		String dateTimeStr = dateTime.toString("yyyy-MM-dd");
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		parms.add(new GlobalParameter("stationCode", stationCode));
		parms.add(new GlobalParameter("dateTime", dateTimeStr));
		String sql = "select t.avg \"value\",\n"
				+ "       t.parmname \"parameterCode\",\n"
				+ "       to_char(t.datatime, 'hh24') \"time\"\n"
				+ "  from monitor_data_hour t\n"
				+ "  left join BC_COLLECTION_INFO t1\n"
				+ "    on t1.device_num = t.mn\n"
				+ " where t1.site_id = @stationCode\n"
				+ "   and t.datatime >= to_date(@dateTime, 'yyyy-mm-dd')\n"
				+ "   and t.datatime < to_date(@dateTime, 'yyyy-mm-dd')+1\n"
				+ " order by t.parmname, t.datatime";
		List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
		rows = NonNullUtil.toList(rows);
		// 校验数值 如果不属于数值，则删除
		List<RowBase> resultRows = new ArrayList<RowBase>();
		for (RowBase rowBase : rows) {
			try {
				String parameterCode = String.valueOf(rowBase.get("parameterCode"));
				Object value = rowBase.get("value");
				Integer time = Integer.valueOf(rowBase.get("time").toString());
				String formatValue = formatPointValue(parameterCode, value);
				if (time != null && !StringUtils.IsNullOrSpace(formatValue)) {
					rowBase.put("value", formatValue);
					resultRows.add(rowBase);
				}
			} catch (Exception e) {

			}
		}
		return NonNullUtil.toList(resultRows);
	}

	// 获取一天的分钟数据 (value,parameterCode,time)
	public List<RowBase> getOneDayMinData(String stationCode, DateTime dateTime) throws Exception {
		ValidUtils.hasText(stationCode, "站点编号为空，无法获取一天的小时数据");
		ValidUtils.notNull(dateTime, "日期为空，无法获取一天的小时数据");
		String dateTimeStr = dateTime.toString("yyyy-MM-dd");
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		parms.add(new GlobalParameter("stationCode", stationCode));
		parms.add(new GlobalParameter("dateTime", dateTimeStr));
		String sql = "select t.avg \"value\",\n"
				+ "       t.parmname \"parameterCode\",\n"
				+ "       to_char(t.datatime, 'hh24:mi') \"time\"\n"
				+ "  from monitor_data_min t\n"
				+ "  left join BC_COLLECTION_INFO t1\n"
				+ "    on t1.device_num = t.mn\n"
				+ " where t1.site_id = @stationCode\n"
				+ "   and t.datatime >= to_date(@dateTime, 'yyyy-mm-dd')\n"
				+ "   and t.datatime < to_date(@dateTime, 'yyyy-mm-dd')+1\n"
				+ " order by t.parmname, t.datatime";
		List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
		rows = NonNullUtil.toList(rows);
		// 校验数值 如果不属于数值，则删除
		final Pattern pattern = Pattern.compile("[0-9]{2}:[0-9]{2}");
		List<RowBase> resultRows = new ArrayList<RowBase>();
		for (RowBase rowBase : rows) {
			try {
				String parameterCode = String.valueOf(rowBase.get("parameterCode"));
				Object value = rowBase.get("value");
				String time = rowBase.get("time").toString();
				String formatValue = formatPointValue(parameterCode, value);
				if (pattern.matcher(time).matches() && !StringUtils.IsNullOrSpace(formatValue)) {
					rowBase.put("value", formatValue);
					resultRows.add(rowBase);
				}
			} catch (Exception e) {

			}
		}
		return NonNullUtil.toList(resultRows);
	}

	public List<RowBase> getAlarmLimit(String stationCode) {
		List<GlobalParameter> parms = new ArrayList<GlobalParameter>();
		String sql = "select t.density_alarm_dowmlimit \"downLimit\",\n"
				+ "       t.density_alarm_uplimit   \"upLimit\",\n"
				+ "       t.site_id                 \"stationCode\",\n"
				+ "       t.name                    \"parameterCode\"\n"
				+ "  from BC_SITE_POLL t\n"
				+ " where 1 = 1\n";
		if (!StringUtils.IsNullOrSpace(stationCode)) {
			parms.add(new GlobalParameter("stationCode", stationCode));
			sql += "   and t.site_id = @stationCode\n";
		}
		sql += " order by t.site_id";
		List<RowBase> rows = DataUtil.getSelectRows(sql, parms);
		return NonNullUtil.toList(rows);
	}

	// 获取当前实时数据的时间
	public String getRuntimeDataTime(String deviceNum) throws Exception {
		List<RowBase> dateTimeList = RemoteService.getInstance().getStationHouseData(deviceNum);
		return dateTimeList.get(0).getSafeString("DATATIME");
	}

	// 获取实时数据{id,name,value,isAlarm}
	public List<Map<String, String>> getRuntimeDataList(String deviceNum) throws Exception {
		HashMap<String, RowBase> dataMap = RemoteService.getStationRealTimeData(deviceNum);
		List<Map<String, String>> valueList = new ArrayList<Map<String, String>>();
		if (!CollectionUtils.isEmpty(dataMap)) {
			Iterator<Entry<String, RowBase>> iterator = dataMap.entrySet().iterator();
			while (iterator.hasNext()) {
				Entry<String, RowBase> next = iterator.next();
				RowBase rowBase = next.getValue();
				Map<String, String> beanMap = createRuntimeDataMap(rowBase);
				valueList.add(beanMap);
			}
		}
		return valueList;
	}

	private Map<String, String> createRuntimeDataMap(RowBase rowBase) {
		Map<String, String> resultMap = new HashMap<String, String>();
		String unit = rowBase.getSafeString("UNIT");
		String valueStr = rowBase.getSafeString("MEAS_NORMAL");

		// 是否报警
		Double alarmUp = optDouble(rowBase.getSafeString("ALARMUP"), Double.MAX_VALUE);
		Double alarmDown = optDouble(rowBase.getSafeString("ALARMDOWN"), Double.MIN_VALUE);
		Double value = optDouble(valueStr, null);
		String isAlarm = "0";
		if (value != null && (value < alarmDown || value > alarmUp)) {
			isAlarm = "1";
		}
		resultMap.put("isAlarm", isAlarm);

		// 参数值(值+单位)并避免出现科学计数法
		String wholeValue = optWholeValue(valueStr);
		if (StringUtils.IsNullOrSpace(wholeValue)) {
			resultMap.put("value", "");
		} else if (StringUtils.IsNullOrSpace(unit)) {
			resultMap.put("value", wholeValue);
		} else {
			resultMap.put("value", wholeValue + unit);
		}
		// 参数名
		resultMap.put("name", rowBase.getSafeString("POLLNAME"));
		// 参数ID
		resultMap.put("id", (String) rowBase.get("POLL"));
		return resultMap;
	}

	private static String getAlarmValueString(String value, String unit) {
		try {
			BigDecimal bd = new BigDecimal(value);
			return bd.toPlainString() + unit;
		} catch (Exception e) {
			return value;
		}
	}

	// 不报错的返回数值
	private Double optDouble(String value, Double defValue) {
		try {
			Double valueOf = Double.parseDouble(value);
			if (valueOf != null && valueOf != Double.NaN) {
				return valueOf;
			}
		} catch (Exception e) {
		}
		return defValue;
	}

	// 返回完整的数值，防止出现科学计数法
	private String optWholeValue(String value) {
		if (value == null || !value.contains("E")) {
			return value;
		}
		Double optDouble = optDouble(value, null);
		if (optDouble == null) {
			return null;
		}
		DecimalFormat df = new DecimalFormat("########.00");
		return df.format(optDouble.doubleValue());
	}

	private String formatPointValue(String parameterCode, Object value) throws Exception {
		return mFormater.NumPointFormat(parameterCode, value, "0");

	}
}
